package com.esyoga.yoyoga.handler;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransOrderQueryModel;
import com.alipay.api.domain.AlipayFundTransToaccountTransferModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayFundTransOrderQueryRequest;
import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayFundTransOrderQueryResponse;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.esyoga.yoyoga.enums.BillTypeEn;
import com.esyoga.yoyoga.enums.UserTypeEn;
import com.esyoga.yoyoga.pojo.TGym;
import com.esyoga.yoyoga.pojo.TPlatform;
import com.esyoga.yoyoga.pojo.TStudent;
import com.esyoga.yoyoga.pojo.TTrainer;
import com.esyoga.yoyoga.service.GymService;
import com.esyoga.yoyoga.service.PayService;
import com.esyoga.yoyoga.service.StudentService;
import com.esyoga.yoyoga.service.TrainerService;
import com.esyoga.yoyoga.util.AlipayConfig;
import com.esyoga.yoyoga.util.OrderNoUtil;
import lombok.Data;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Data
@Controller
@RequestMapping("/pay")
public class PayController {
    @Resource
    PayService payService;
    @Resource
    StudentService studentService;
    @Resource
    TrainerService trainerService;
    @Resource
    GymService gymService;

    private static AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
    /**
     * 充值
     * @param fee 充值金额
     */

    @ResponseBody
    @RequestMapping("/recharge")
    public String recharge(double fee, HttpServletRequest request) throws AlipayApiException {
        String rechargeOrderNum = OrderNoUtil.orderNoGenerate();
        String subject = "充值订单";

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        //付款金额，必填
        String total_amount = new String(String.valueOf(fee));

        //因为异步返回时的session不是本地客户端的session，无法通过session获取用户类型和用户Id，所以先存起来.
        //存在extra_common_param里面，以逗号隔开
        HttpSession session = request.getSession();
        UserTypeEn userTypeEn = (UserTypeEn) session.getAttribute("userTypeEn");
        Object user = session.getAttribute("user");
        Integer uId = null;
        switch (userTypeEn){
            case STUDENT:
                uId = ((TStudent)user).getsId();
                break;
            case TRAINER:
                uId = ((TTrainer)user).gettId();
                break;
            case GYM:
                uId = ((TGym)user).getgId();
                break;
            case PLATFORM:
                uId = ((TPlatform)user).getpId();
                break;
        }


        alipayRequest.setBizContent("{\"out_trade_no\":\""+ rechargeOrderNum +"\","
                + "\"total_amount\":\""+ total_amount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"passback_params\":\""+ uId+","+userTypeEn.getCode() +"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        return result;
    }


    /**
     * 支付宝提现接口
     * @param payee_account 提现收款账户，只能为支付宝账号
     * @param money 提现金额
     * 前端需要传入的数据：
     *
     *
     */
    @RequestMapping("/transfer")
    @ResponseBody
    public String transfer(String payee_account,String money,HttpServletRequest request) throws AlipayApiException {
        //判断用户数据库中余额是否大于提现金额

        String orderNo = OrderNoUtil.orderNoGenerate();//订单号

        AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();
        model.setOutBizNo(orderNo);//生成订单号
        model.setPayeeType("ALIPAY_LOGONID");//固定值
        model.setPayeeAccount(payee_account);//转账收款账户
        model.setAmount(money);//提现金额
        model.setPayerShowName("提现");
        model.setPayerRealName("沙箱环境");//账户真实名称
        model.setRemark("提现");

        AlipayFundTransToaccountTransferResponse response = transferToResponse(model);
        String result = response.getBody();
        System.out.println("transfer result>"+result);

        HttpSession session = request.getSession();
        UserTypeEn userTypeEn = (UserTypeEn) session.getAttribute("userTypeEn");
        Object user = session.getAttribute("user");

        Integer uId = null;
        switch (userTypeEn){
            case STUDENT:
                uId = ((TStudent)user).getsId();
                break;
            case TRAINER:
                uId = ((TTrainer)user).gettId();
                break;
            case GYM:
                uId = ((TGym)user).getgId();
                break;
            case PLATFORM:
                uId = ((TPlatform)user).getpId();
                break;
        }

        if (response.isSuccess()) {
            //更新数据库中的用户余额以及插入一条流水
            payService.updateBalanceAndInsertBillRecord(
                    BillTypeEn.TRANSFER,
                    orderNo,
                    response.getOrderId(),
                    new BigDecimal(money).negate(),//减少用户钱包，因此使用负数
                    uId,
                    userTypeEn);
            return "成功了";
        } else {
            System.out.println("失败");
//            //调用查询接口查询数据
//            JSONObject jsonObject = JSONObject.parseObject(result);
//            String out_biz_no = jsonObject.getJSONObject("alipay_fund_trans_toaccount_transfer_response").getString("out_biz_no");
//            AlipayFundTransOrderQueryModel queryModel = new AlipayFundTransOrderQueryModel();
//            model.setOutBizNo(out_biz_no);
//            boolean isSuccess = transferQuery(queryModel);
//            if (isSuccess) { r
//                return true;
//            }
        }
        return "失败了";

    }

    /**
     * 提现操作
     * @param model
     * @return
     * @throws AlipayApiException
     */
    public static AlipayFundTransToaccountTransferResponse transferToResponse(AlipayFundTransToaccountTransferModel model) throws AlipayApiException{
        AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
        request.setBizModel(model);
        return alipayClient.execute(request);
    }

    /**
     * * 转账查询接口
     * @param
     * @return
     * @throws AlipayApiException
     */
    public static boolean transferQuery(AlipayFundTransOrderQueryModel model) throws AlipayApiException{
        AlipayFundTransOrderQueryResponse response = transferQueryToResponse(model);
        System.out.println("transferQuery result>"+response.getBody());
        if(response.isSuccess()){
            return true;
        }
        return false;
    }
    public static AlipayFundTransOrderQueryResponse transferQueryToResponse(AlipayFundTransOrderQueryModel model) throws AlipayApiException{
        AlipayFundTransOrderQueryRequest request = new AlipayFundTransOrderQueryRequest();
        request.setBizModel(model);
        return alipayClient.execute(request);
    }



    /**
     * 异步通知，将用户的支付信息存储到数据库
     * @throws Exception
     */
    @RequestMapping("/notify")
    @ResponseBody
    public void updateOrder(HttpServletResponse response, HttpServletRequest request) throws Exception {
        //将用户的支付信息存储到数据库
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map<String,String[]> requestParams = request.getParameterMap();

        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";

            }
            System.out.println("name:"+name+"   value:"+valueStr);
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名

        System.out.println("signVerified:"+signVerified);

        if(signVerified) {//验证成功
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
            //支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
            //交易状态
            String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
            //交易金额
            String total_money = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");
            BigDecimal money = new BigDecimal(total_money);
            //获取uId和userType
            String userIdAndType = request.getParameter("passback_params");
            Integer uId = Integer.valueOf(userIdAndType.split(",")[0]);
            Integer userType = Integer.valueOf(userIdAndType.split(",")[1]);
            UserTypeEn userTypeEn = UserTypeEn.getUserTypeEnByCode(userType);

            if(trade_status.equals("TRADE_FINISHED")){
                //TRADE_FINISHED啥意思，先不管了

            }else if (trade_status.equals("TRADE_SUCCESS")){
                System.out.println("支付成功");
                //更新数据库中的用户余额以及插入一条流水
                payService.updateBalanceAndInsertBillRecord(BillTypeEn.RECHARGE,out_trade_no,trade_no,money,uId,userTypeEn);

            }
            try {
                response.getWriter().println("success");
            } catch (IOException e) {
                e.printStackTrace();
            }

        }else {//验证失败
            try {
                response.getWriter().println("fail");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 同步通知，支付成功后跳转到充值界面
     * @param response
     */
    @RequestMapping("/syn")
    public void syn(HttpServletResponse response,HttpServletRequest request) {

        try {
            response.sendRedirect("http://localhost:8080/index.html");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
